
#include "../iface/debug.h"
#include "XMLReader.h"
#include "XMLWriter.h"
#include "DOMDocument.h"

int DOMDocument::ReadIn(const char *buffer, int length)
{
   XMLReader xmlreader;
   int wassuccess = 0;
   int wasvsuccess = 0;
//   tdoc = xmlreader.XMLRead(filename, &wassuccess, &wasvsuccess);
   // Don't validate!
   if (tdoc) xmlFreeDoc(tdoc);
   tdoc = xmlreader.XMLRead(buffer, length, &wassuccess, NULL);
   if (!wassuccess)
   {
      errprint("failed to parse buffer");
      tdoc = xmlNewDoc(BAD_CAST "1.0");
      return 1;
   }
   return 0;
}

int DOMDocument::ReadIn(const char *filename)
{
   XMLReader xmlreader;
   int wassuccess = 0;
   int wasvsuccess = 0;
//   tdoc = xmlreader.XMLRead(filename, &wassuccess, &wasvsuccess);
   // Don't validate!
   if (tdoc) xmlFreeDoc(tdoc);
   tdoc = xmlreader.XMLRead(filename, &wassuccess, NULL);
   if (!wassuccess)
   {
      errprint("failed to parse file '%s'", filename);
      tdoc = xmlNewDoc(BAD_CAST "1.0");
      return 1;
   }
   //if (!wasvsuccess) errprint("failed to validate file '%s'", filename);
   return 0;
}

DOMDocument::DOMDocument(const char *buffer, int length)
{
   tdoc = NULL;
   ReadIn(buffer, length);
}

DOMDocument::DOMDocument(const char *filename)
{
   tdoc = NULL;
   ReadIn(filename);
}

DOMDocument::DOMDocument()
{
   tdoc = xmlNewDoc(BAD_CAST "1.0");
}

DOMDocument::~DOMDocument()
{
   xmlFreeDoc(tdoc);
}

xmlNodePtr DOMDocument::GetRootNode()
{
   return xmlDocGetRootElement(tdoc);
}

void DOMDocument::GenerateRootNode(const char *name)
{
   xmlNodePtr n = xmlNewNode(NULL, BAD_CAST name);
   xmlDocSetRootElement(tdoc, n);
}

void DOMDocument::SetProperty(xmlNodePtr node, const char *key, const char *value)
{
   xmlNewProp(node, BAD_CAST key, BAD_CAST value);
}

xmlNodePtr DOMDocument::CreateChildNode(xmlNodePtr node, const char *name)
{
   return xmlNewChild(node, NULL, BAD_CAST name, NULL);
}

xmlNodePtr DOMDocument::FindNode(xmlNodePtr node, const char *name)
{
   if (strcmp((const char *)node->name, name) == 0) return node;
   if (node->children)
   {
      xmlNodePtr anychildren = FindNode(node->children, name);
      if (anychildren != NULL) return anychildren;
   }
   if (node->next)
   {
      xmlNodePtr anynext = FindNode(node->next, name);
      if (anynext != NULL) return anynext;
   }
   return NULL;
}

xmlNodePtr DOMDocument::FindNode(xmlNodePtr node, const char *name, const char *attribname, const char *attribvalue)
{
   if (strcmp((const char *)node->name, name) == 0)
   {
      if (xmlHasProp(node, BAD_CAST attribname) != NULL)
      {
         xmlChar *valstring = xmlGetProp(node, BAD_CAST attribname);
         if (strcmp((const char *)valstring, attribvalue) == 0)
         {
            xmlFree(valstring);
            return node;
         } else xmlFree(valstring);
      }
   }
   if (node->children)
   {
      xmlNodePtr anychildren = FindNode(node->children, name);
      if (anychildren != NULL) return anychildren;
   }
   if (node->next)
   {
      xmlNodePtr anynext = FindNode(node->next, name);
      if (anynext != NULL) return anynext;
   }
   return NULL;
}

int DOMDocument::HasAttrib(xmlNodePtr node, const char *attribname)
{
   return (xmlHasProp(node, BAD_CAST attribname) != NULL);
}

char *DOMDocument::GetAttribValueString(xmlNodePtr node, const char *attribname)
{
   xmlChar *attribval = xmlGetProp(node, BAD_CAST attribname);
   if (attribval == NULL) return NULL;
   int len = xmlStrlen(attribval);
   char *attribcval = (char *)malloc(sizeof(xmlChar)*(len+1));
   memcpy(attribcval, attribval, sizeof(xmlChar)*(len+1));
   xmlFree(attribval);
   return attribcval;
}

int DOMDocument::WriteOut(const char *filename)
{
   XMLWriter xmlwriter;
   return xmlwriter.XMLWrite(filename, tdoc);
}

int DOMDocument::WriteOut(xmlBufferPtr buffer)
{
   XMLWriter xmlwriter;
   return xmlwriter.XMLWrite(buffer, tdoc);
}
